package com.qdxht.dispenser.ui.activity.main;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import androidx.viewpager2.widget.ViewPager2;
import android.widget.RelativeLayout;
import java.io.DataOutputStream;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Calendar;
import java.util.Iterator;
import org.json.JSONObject;
import com.android.xhapimanager.XHApiManager;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.bumptech.glide.Glide;
import com.hjq.gson.factory.GsonFactory;
import com.hjq.http.listener.OnDownloadListener;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.hjq.toast.ToastUtils;
import com.qdxht.dispenser.R;
import com.qdxht.dispenser.base.BaseActivity;
import com.qdxht.dispenser.databinding.ActivityMainBinding;
import com.qdxht.dispenser.service.MqttManagerService;
import com.qdxht.dispenser.service.WatchdogClient;
import com.qdxht.dispenser.ui.activity.test.PlayResourcesBean;
import com.qdxht.dispenser.ui.activity.test.TestActivity;
import com.qdxht.dispenser.ui.models.entity.AdContent;
import com.qdxht.dispenser.ui.models.entity.MLatLng;
import com.qdxht.dispenser.ui.view.adapter.PlayAdapter;
import com.qdxht.dispenser.utils.BroadcastUtil;
import com.qdxht.dispenser.utils.ConfigUtil;
import com.qdxht.dispenser.utils.DateUtil;
import com.qdxht.dispenser.utils.DeviceIdUtil;
import com.qdxht.dispenser.utils.DownloadUtil;
import com.qdxht.dispenser.utils.GPSUtils;
import com.qdxht.dispenser.utils.InstallApkUtil;
import com.qdxht.dispenser.utils.MediaTypeChecker;
import com.qdxht.dispenser.utils.RoundedQRCode;
import com.qdxht.dispenser.utils.SpUtils;
import com.shuyu.gsyvideoplayer.GSYVideoManager;
import com.youth.banner.Banner;
import com.youth.banner.listener.OnPageChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Comparator;
import com.qdxht.dispenser.service.SerialPortService;
import com.qdxht.dispenser.service.SerialPortServiceHelper;
import com.qdxht.dispenser.service.MqttSerialBridge;
import com.qdxht.dispenser.utils.MqttUtil;
import timber.log.Timber;

/**
 * 设置页面
 */
public class MainActivity extends BaseActivity<ActivityMainBinding> {

    private static final String TAG = "MainActivity";

    public static void start(Context context) {
        Intent intent = new Intent(context, MainActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected ActivityMainBinding getBinding() {
        return ActivityMainBinding.inflate(getLayoutInflater());
    }

    private static final long LOOP_TIME = 6000L;
    private int currentPos = 1;
    private Handler taskHandler;
    private PlayAdapter adapter;
    private Banner<PlayResourcesBean, PlayAdapter> banner;
    private List<PlayResourcesBean> resourcesList;
    private SerialPortServiceHelper serialPortServiceHelper;
    private SerialPortService serialPortService;
    private MqttSerialBridge mqttSerialBridge;
    private BroadcastReceiver adReceiver;

    // 用于存储每个广告的播放次数
    private HashMap<String, Integer> adPlayCountMap = new HashMap<>();
    // 一小时的毫秒数
    private static final long HOUR_IN_MILLIS = 60 * 60 * 1000;

    private long watchdogMillis = 30;
    // 主板厂商SDK
    XHApiManager apiManager;

    // 跟踪背光状态，避免重复操作
    private boolean isBacklightOn = true; // 默认认为开机时背光是开启的

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 100: {
                    mHandler.sendEmptyMessageDelayed(100,1000 * 60 * 5);
                    mqttSerialBridge.getDeviceState(signalIntensity);
                    break;
                }
                case 200: {
                    if(apiManager != null){
                        mHandler.sendEmptyMessageDelayed(200,1000 * watchdogMillis);
                        apiManager.XHWatchDogFeed();
                    } else if(watchdogClient != null){
                        if(watchdogClient.connect()){
                            Timber.tag(TAG).i("绑定看门狗服务成功");
                        } else {
                            Timber.tag(TAG).e("绑定看门狗服务失败");
                        }
                    }
                    break;
                }
                case 300: {
                    // 每分钟检查一次背光状态
                    mHandler.sendEmptyMessageDelayed(300, 1000 * 60);
                    checkBacklight();
                    break;
                }
                case MSG_MQTT_CHECK: {
                    // 定期检查MQTT连接状态
                    checkMqttConnection();
                    // 继续安排下一次检查
                    mHandler.sendEmptyMessageDelayed(MSG_MQTT_CHECK, MQTT_CHECK_INTERVAL);
                    break;
                }
                case 888: {
                    // 授权判断
                    if(DateUtil.checkDate("2025-12-20")){
                        finish();
                        return;
                    }
                    break;
                }
                default:
                    break;
            }
        };
    };

    WatchdogClient watchdogClient;

    @Override
    protected void initView() {
        int randomNumber = (int) (Math.random() * 20) + 20;
        mHandler.sendEmptyMessageDelayed(888, 1000L * randomNumber);
        // 主板系统有5.0和7.1, 7.1的不支持jar
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            apiManager = new XHApiManager();
            // 开启电子狗
            apiManager.XHWatchDogEnable(true);
        } else {
            watchdogClient = new WatchdogClient(this, "com.qdxht.dispenser.ui.activity.main.MainActivity");
        }
        // 获取信号强度，获取文件权限
        requestPermissionSignal();
    }

    private void initAllData() {
        // 先从本地存储加载之前保存的广告播放次数
        loadAdPlayCount();
        // 启用的设备加载广告
        initEnableDevice();
        // 加载二维码
        initQRCode();
        // 设置开关机
        initTimerSwitch();
        binding.version.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SettingsActivity.start(mActivity);
            }
        });
//        binding.number.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                TestActivity.start(mActivity);
//            }
//        });

        adReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (BroadcastUtil.ACTION_SET_AD.equals(intent.getAction())) {
                    String content = intent.getStringExtra(BroadcastUtil.ACTION_CONTENT);
                    if (content != null) {
                        AdContent adContent = GsonFactory.getSingletonGson().fromJson(content, AdContent.class);
                        reloadBannerWithAd(adContent);
                    }
                } else if (BroadcastUtil.ACTION_ENABLE_DEVICE.equals(intent.getAction())) {
                    initEnableDevice();
                } else if (BroadcastUtil.ACTION_QRCODE.equals(intent.getAction())) {
                    initQRCode();
                } else if (BroadcastUtil.ACTION_INVENTORY.equals(intent.getAction())) {
                    binding.number.setText(ConfigUtil.getInventory() + "");
                } else if (BroadcastUtil.ACTION_TIMERSWITCH.equals(intent.getAction())) {
                    initTimerSwitch();
                    // 设置改变后立即检查一次背光状态
                    checkBacklight();
                } else if (BroadcastUtil.ACTION_DOWNLOAD_UPDATE.equals(intent.getAction())) {
                    // 设置下次清理缓存，更新上报标记
                    ConfigUtil.setCacheClear(true);
                    String url = intent.getStringExtra(BroadcastUtil.ACTION_CONTENT);
                    download(url);
                }
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(BroadcastUtil.ACTION_SET_AD);
        filter.addAction(BroadcastUtil.ACTION_ENABLE_DEVICE);
        filter.addAction(BroadcastUtil.ACTION_QRCODE);
        filter.addAction(BroadcastUtil.ACTION_INVENTORY);
        filter.addAction(BroadcastUtil.ACTION_TIMERSWITCH);
        filter.addAction(BroadcastUtil.ACTION_DOWNLOAD_UPDATE);
        registerReceiver(adReceiver, filter);

        // 定时喂狗
        mHandler.sendEmptyMessageDelayed(200,1000 * 30);
        // 启动MQTT连接状态监控
        mHandler.sendEmptyMessageDelayed(MSG_MQTT_CHECK, MQTT_CHECK_INTERVAL);

        String androidId = DeviceIdUtil.getAndroidId(this);
        // 主板信息
        binding.version.setText(androidId.substring(androidId.length() - 4));
        binding.number.setText(ConfigUtil.getInventory() + "");
        // 1. 初始化并绑定串口服务
        serialPortServiceHelper = new SerialPortServiceHelper(this, new SerialPortServiceHelper.ServiceConnectionCallback() {
            @Override
            public void onServiceConnected(SerialPortService service) {
                serialPortService = service;
                // 扫描串口，并连接
                serialPortService.scanAndConnectPort(null);
                // 3. 启动桥接
                mqttSerialBridge = new MqttSerialBridge(MainActivity.this, serialPortService);
            }
            @Override
            public void onServiceDisconnected() {
                serialPortService = null;
            }
        });
        serialPortServiceHelper.bindService();
        // 2. 启动MQTT服务
        MqttUtil.init(MainActivity.this, new MqttManagerService.MqttEventCallbackAdapter() {
            @Override
            public void onConnectSuccess() {
                mqttConnected = true;
                reconnectAttempts = 0;
                reconnectDelay = 5000; // 重置重连延迟
                Timber.tag(TAG).i("MQTT连接成功");
                initConnectData();
            }
            
            @Override
            public void onConnectFailure(Throwable cause) {
                mqttConnected = false;
                Timber.tag(TAG).e(cause, "MQTT连接失败");
                // 触发重连逻辑
                scheduleReconnect();
            }
            
            @Override
            public void onConnectionLost(Throwable cause) {
                mqttConnected = false;
                Timber.tag(TAG).e(cause, "MQTT连接丢失");
            }
        });
    }

    boolean isInit = false;

    private void initConnectData() {
        if(mqttSerialBridge != null){
            mqttSerialBridge.start();
        }
        // 定时上报硬件状态
        mHandler.sendEmptyMessageDelayed(100,1000 * 10);
        if(isInit){
            return;
        }
        // 初始化广告播放计数上报定时器（在mqttSerialBridge初始化后调用）
        initAdPlayCountReportTimer();
        // 请求定位权限
        requestPermission();
        // 判断是否需要清理缓存，上报更新完成
        if(ConfigUtil.getCacheClear()){
            Timber.tag(TAG).i("更新后，需要清空缓存:%s", DownloadUtil.URL_FILE_PATH);
            DownloadUtil.deleteFolderFile(DownloadUtil.URL_FILE_PATH, true);
            ConfigUtil.setCacheClear(false);
            // 上报更新完成
            mqttSerialBridge.sendMqttUpdateCompleted();
        }
        isInit = true;
    }

    @Override
    protected void initData() {
    }

    private void initBanner() {
        taskHandler = new Handler(Looper.getMainLooper());
        resourcesList = ConfigUtil.getAdList();
//        resourcesList.add(new PlayResourcesBean("file:///android_asset/banner.jpg", true, "图片"));
//        resourcesList.add(new PlayResourcesBean("https://upload-images.jianshu.io/upload_images/5809200-a99419bb94924e6d.jpg", true, "图片"));
//        resourcesList.add(new PlayResourcesBean("https://s10.mogucdn.com/mlcdn/c45406/170831_479g0ifl6f2i313feb5ech46kek21_778x440.jpg", true, "图片"));
//        resourcesList.add(new PlayResourcesBean("https://media.w3.org/2010/05/sintel/trailer.mp4", false, "视频"));
        adapter = new PlayAdapter(this, resourcesList, this);

        banner = binding.banner;
        banner.addBannerLifecycleObserver(this)
                .setAdapter(adapter, true)
                .setLoopTime(LOOP_TIME);

        banner.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                if (position == banner.getRealCount() - 1) {
                    currentPos = banner.getRealCount();
                } else if (position == 0) {
                    currentPos = 1;
                } else {
                    currentPos = position + 1;
                }

                try {
                    banner.setLoopTime(resourcesList.get(position).getShowDuration() * 1000);
                    // 增加广告播放计数
                    if (position < resourcesList.size()) {
                        // 尝试从资源ID获取广告ID
                        PlayResourcesBean resource = resourcesList.get(position);
                        incrementAdPlayCount(resource.getId());
                    }
                } catch (Exception e) {
                    Timber.tag(TAG).e(e, "处理广告播放计数异常");
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state == ViewPager2.SCROLL_STATE_IDLE) {
                    if (banner.isInfiniteLoop()) {
                        taskHandler.post(task);
                    }
                }
            }
        });
    }

    private final Runnable task = new Runnable() {
        @Override
        public void run() {
            if (adapter.getVHMap().containsKey(currentPos)) {
                if (adapter.getVHMap().get(currentPos) instanceof PlayAdapter.VideoHolder) {
                    PlayAdapter.VideoHolder holder = (PlayAdapter.VideoHolder) adapter.getVHMap().get(currentPos);
                    GSYVideoManager.onPause();
                    holder.video.startPlayLogic();
                    banner.isAutoLoop(true);
                    banner.stop();
                    banner.isAutoLoop(false);
                } else {
                    GSYVideoManager.onPause();
                    banner.isAutoLoop(true);
                    banner.start();
                }
            } else {
                GSYVideoManager.onPause();
                banner.isAutoLoop(true);
                banner.start();
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        if(taskHandler != null){
            taskHandler.post(task);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        GSYVideoManager.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        // 移除所有MQTT检查和重连任务
        mHandler.removeMessages(MSG_MQTT_CHECK);
        mHandler.removeCallbacksAndMessages(MQTT_RECONNECT_TOKEN);
        
        // 确保保存当前广告播放计数
        if (!adPlayCountMap.isEmpty()) {
            storeAdPlayCount();
            Timber.tag(TAG).d("应用关闭前保存广告播放计数");
        }
        
        // 释放资源
        GSYVideoManager.releaseAllVideos();
        if(banner != null){
            banner.destroy();
        }
        if (serialPortServiceHelper != null) {
            serialPortServiceHelper.unbindService();
        }
        if (adReceiver != null) {
            unregisterReceiver(adReceiver);
        }
        if (mLocationClient != null) {
            mLocationClient.stop();
        }
        if (telephonyManager != null && phoneStateListener != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }

    /**
     * 增加广告播放次数
     * @param adId 广告ID
     */
    private void incrementAdPlayCount(String adId) {
        Integer count = adPlayCountMap.get(adId);
        if (count == null) {
            count = 0;
        }
        adPlayCountMap.put(adId, count + 1);
        
        // 每次增加计数时都保存到本地存储，避免程序异常退出时丢失数据
        storeAdPlayCount();
    }
    
    /**
     * 将内存中的广告播放计数保存到本地存储
     */
    private void storeAdPlayCount() {
        try {
            // 将当前的广告播放计数转换为JSON格式存储
            JSONObject countData = new JSONObject();
            for (Map.Entry<String, Integer> entry : adPlayCountMap.entrySet()) {
                countData.put(entry.getKey(), entry.getValue());
            }
            // 保存到本地存储
            SpUtils.encode("ad_play_count", countData.toString());
            Timber.tag(TAG).d("广告播放计数已保存到本地存储");
        } catch (Exception e) {
            Timber.tag(TAG).e(e, "保存广告播放计数到本地存储失败");
        }
    }
    
    /**
     * 从本地存储加载广告播放计数
     */
    private void loadAdPlayCount() {
        try {
            String storedDataStr = SpUtils.decodeString("ad_play_count");
            if (TextUtils.isEmpty(storedDataStr)) {
                return; // 没有存储的数据
            }
            
            JSONObject storedData = new JSONObject(storedDataStr);
            
            // 清除当前内存中的计数
            adPlayCountMap.clear();
            
            // 加载存储的播放计数
            Iterator<String> keys = storedData.keys();
            while (keys.hasNext()) {
                String adId = keys.next();
                int count = storedData.optInt(adId, 0);
                adPlayCountMap.put(adId, count);
            }
            Timber.tag(TAG).d("已从本地存储加载广告播放计数");
        } catch (Exception e) {
            Timber.tag(TAG).e(e, "从本地存储加载广告播放计数失败");
        }
    }



    /**
     * 生成并上报广告播放次数
     */
    private void reportAdPlayCount() {
        // 没有播放记录或所有广告播放次数为0则不上报
        boolean hasPlayCount = false;
        for (Integer count : adPlayCountMap.values()) {
            if (count > 0) {
                hasPlayCount = true;
                break;
            }
        }
        
        if (!hasPlayCount) {
            Timber.tag(TAG).d("没有广告播放记录，跳过本次上报");
            return;
        }
        // 发送上报请求
        if (mqttSerialBridge != null) {
            mqttSerialBridge.sendMqttAdPlayCount(adPlayCountMap);
            // 上报成功后会在sendMqttAdPlayCount方法中清空计数和本地存储
        } else {
            Timber.tag(TAG).w("MQTT桥接服务未初始化，无法上报广告播放次数");
        }
    }

    /**
     * 初始化广告播放计数上报定时器
     * 设置每小时整点触发一次上报
     */
    private void initAdPlayCountReportTimer() {
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        // 计算到下一个整点的时间
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long initialDelay = calendar.getTimeInMillis() - System.currentTimeMillis();
        // 创建静态Handler避免内存泄漏
        final Handler adPlayCountReportHandler = new Handler(Looper.getMainLooper());
        
        // 创建定时上报任务
        final Runnable reportTask = new Runnable() {
            @Override
            public void run() {
                try {
                    // 上报广告播放次数
                    reportAdPlayCount();
                } catch (Exception e) {
                    Timber.tag(TAG).e(e, "定时上报广告播放次数异常");
                } finally {
                    // 无论是否成功都重新调度下一次上报（每小时）
                    adPlayCountReportHandler.postDelayed(this, HOUR_IN_MILLIS);
                }
            }
        };
        // 启动定时任务
        adPlayCountReportHandler.postDelayed(reportTask, initialDelay);
        Timber.tag(TAG).d("广告播放计数定时上报初始化完成，下次上报时间: %s",
                DateUtil.formatDateTime(calendar.getTime()));
    }

    public Banner<PlayResourcesBean, PlayAdapter> getBanner() {
        return banner;
    }

    public long getLoopTime() {
        return LOOP_TIME;
    }


    private void reloadBannerWithAd(AdContent adContent) {
        List<PlayResourcesBean> list = ConfigUtil.getAdList();
        List<PlayResourcesBean> addList = new ArrayList<>();
        List<AdContent.UrlListDTO> listDTOS = adContent.getUrlList();
        for(AdContent.UrlListDTO dto : listDTOS){
            PlayResourcesBean bean = null;
            if("img".equals(dto.getType())){
                bean = new PlayResourcesBean(dto.getUrl(), true, dto.getId(), dto.getWeight(), dto.getShowDuration());
            } else if("video".equals(dto.getType())){
                bean = new PlayResourcesBean(dto.getUrl(), false, dto.getId(), dto.getWeight(), dto.getShowDuration());
            } else {
                if(MediaTypeChecker.isImageUrl(dto.getUrl())){
                    bean = new PlayResourcesBean(dto.getUrl(), true, dto.getId(), dto.getWeight(), dto.getShowDuration());
                } else if(MediaTypeChecker.isVideoUrl(dto.getUrl())){
                    bean = new PlayResourcesBean(dto.getUrl(), false, dto.getId(), dto.getWeight(), dto.getShowDuration());
                }
            }
            if(bean != null){
                if(dto.getOperation() == 1){//新增
                    addList.add(bean);
                } else { // 删除
                    removeAd(list, bean.getId());
                }
            }
        }
        // 添加广告
        addAllAd(list, addList);
        // 按weight降序排序，权重越大越靠前
        Collections.sort(list, new Comparator<PlayResourcesBean>() {
            @Override
            public int compare(PlayResourcesBean o1, PlayResourcesBean o2) {
                return Integer.compare(o2.getWeight(), o1.getWeight());
            }
        });
        Timber.tag(TAG).i("广告数量：%s", list.size());
        // 保存广告数据到本地
        ConfigUtil.setAdList(list);
        resourcesList.clear();
        resourcesList.addAll(list);
        banner.getAdapter().notifyDataSetChanged();
    }

    private void addAllAd(List<PlayResourcesBean> list, List<PlayResourcesBean> addList) {
        if(addList.isEmpty()){
            return;
        }
        // 新增广告ID与之前保存的ID相同，删除
        List<String> rmList = new ArrayList<>();
        if(!list.isEmpty()){
            for(PlayResourcesBean ad : addList){
                for(PlayResourcesBean lst : list){
                    if(ad.getId().equals(lst.getId())){
                        rmList.add(ad.getId());
                    }
                }
            }
        }
        if(!rmList.isEmpty()){
            for(String id : rmList){
                removeAd(list, id);
            }
        }
        list.addAll(addList);
    }

    private void removeAd(List<PlayResourcesBean> list, String id) {
        if(TextUtils.isEmpty(id) || list.isEmpty()){
            return;
        }
        List<PlayResourcesBean> rmList = new ArrayList<>();
        for(PlayResourcesBean dto : list){
           if(id.equals(dto.getId())){
               rmList.add(dto);
           }
        }
        if(!rmList.isEmpty()){
            list.removeAll(rmList);
        }
    }

    public void initEnableDevice() {
        boolean enable = ConfigUtil.getEnableDevice();
        if(enable){//启用设备
            if(banner != null){
                banner.destroy();
            }
            initBanner();
            binding.disableImage.setVisibility(View.GONE);
        } else {//停用设备
            Glide.with(this)
                    .load(ConfigUtil.getEnableImage())
                    .into(binding.disableImage);
            binding.disableImage.setVisibility(View.VISIBLE);

            // 清空广告播放
            if(banner != null){
                resourcesList.clear();
                banner.getAdapter().notifyDataSetChanged();
                banner.destroy();
            }
        }
    }

    public void initQRCode() {
        String qrCode = ConfigUtil.getQRCode();
        if(!TextUtils.isEmpty(qrCode)){
            try {
                // 获取配置的二维码大小
                int qrCodeSize = ConfigUtil.getQRCodeSize();
                // 获取配置的偏移值
                int horizontalOffset = ConfigUtil.getQRCodeHorizontalOffset();
                int verticalOffset = ConfigUtil.getQRCodeVerticalOffset();
                // 设置二维码的位置
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) binding.llQrcode.getLayoutParams();
                params.leftMargin = horizontalOffset;
                params.bottomMargin = verticalOffset;
                binding.llQrcode.setLayoutParams(params);
                // 生成二维码
                Bitmap qrBitmap = RoundedQRCode.create(this,
                        qrCode, // 二维码内容
                        qrCodeSize,                   // 二维码大小
                        BitmapFactory.decodeResource(getResources(), R.mipmap.ic_qr_logo), // 自定义Logo
                        Color.parseColor("#24A34C")             // 二维码颜色
                );
                // 设置二维码
                binding.qrCode.setImageBitmap(qrBitmap);
                binding.llQrcode.setVisibility(View.VISIBLE);
            } catch (Exception e) {
                Timber.tag(TAG).e(e, "二维码生成失败");
            }
        } else {
            binding.llQrcode.setVisibility(View.GONE);
        }
    }

    private void requestPermission() {
        XXPermissions.with(this)
                .permission(Manifest.permission.ACCESS_FINE_LOCATION)
                .permission(Manifest.permission.ACCESS_COARSE_LOCATION)
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all) {
                            startLocation();
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        if (never) {
                            ToastUtils.show("请在系统设置中授予定位权限");
                            XXPermissions.startPermissionActivity(MainActivity.this, permissions);
                        } else {
                            ToastUtils.show("获取定位权限失败");
                        }
                    }
                });
    }

    private LocationClient mLocationClient;
    private int count = 1;

    private MLatLng lastLat;

    // MQTT 连接状态监控相关常量和变量
    private static final int MSG_MQTT_CHECK = 400;
    private static final int MQTT_CHECK_INTERVAL = 30 * 1000; // 30秒检查一次连接状态
    private static final int MAX_RECONNECT_DELAY = 2 * 60 * 1000; // 最大重连延迟2分钟
    private int reconnectDelay = 5000; // 初始重连延迟5秒
    private int reconnectAttempts = 0; // 重连尝试次数
    private boolean mqttConnected = false; // MQTT连接状态

    public void startLocation() {
        try {
            // 初始化定位
            mLocationClient = new LocationClient(getApplicationContext());
            LocationClientOption option = new LocationClientOption();
            // 设置定位模式为高精度模式
            option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
            // 设置坐标系类型
            option.setCoorType("bd09ll");
            // 设置发起定位请求的间隔时间 10分钟定位一次
            option.setScanSpan(1000 * 60 * 10);
            option.setOpenGnss(true);
            // 设置是否需要地址信息
            option.setIsNeedAddress(true);
            // 设置是否需要位置语义化结果
            // 设置是否需要返回位置POI信息
            option.setIsNeedLocationPoiList(true);
            // 设置是否打开gps
            option.setOpenGps(true);
            // 设置是否需要返回新鲜度
            // 设置定位SDK内部是否使用缓存
            option.setEnableSimulateGps(false);
            mLocationClient.setLocOption(option);
            mLocationClient.registerLocationListener(new BDAbstractLocationListener() {
                @Override
                public void onReceiveLocation(BDLocation location) {
                    if (location == null) {
                        Timber.tag(TAG).i("定位失败");
                        return;
                    }
                    MLatLng latLng = GPSUtils.bd09ToGps(location.getLatitude(),location.getLongitude());
                    if(lastLat != null){
                        double distance = GPSUtils.gps2m(lastLat.getLatitude(),lastLat.getLongitude(),
                                latLng.getLatitude(),latLng.getLongitude());
                        if(distance >= ConfigUtil.getGPSAlarmThreshold()){
                            mqttSerialBridge.sendMqttGpsAlarm(location.getLongitude(),location.getLatitude(),location.getAddrStr());
                            Timber.tag(TAG).i("移动范围超过定位偏差阈值时报警:"+ ConfigUtil.getGPSAlarmThreshold() + " 偏差："+distance);
                        }
                        Timber.tag(TAG).i("移动范围:"+ ConfigUtil.getGPSAlarmThreshold() + " 偏差："+distance);
                    }
                    // 判断距离偏移
                    if(count % 3 == 0){ //定位3次上报一次
                        mqttSerialBridge.sendMqttGpsInfo(location.getLongitude(),location.getLatitude(),location.getAddrStr());
                        Timber.tag(TAG).i("位置信息上报:" + location.getAddrStr());
                    }
                    count++;
                    lastLat = latLng;
                    Timber.tag(TAG).i("定位结果: "+location.getLongitude() + " " + location.getLatitude() +" " +location.getAddrStr());
                }
            });
            mLocationClient.start();
        } catch (Exception e) {
            e.printStackTrace();
            ToastUtils.show("初始化定位失败：" + e.getMessage());
        }
    }



    private TelephonyManager telephonyManager;
    private PhoneStateListener phoneStateListener;

    private void requestPermissionSignal() {
        XXPermissions.with(this)
                .permission(Manifest.permission.READ_PHONE_STATE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all) {
                            initSignalStrengthMonitor();
                            initAllData();
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        if (never) {
                            ToastUtils.show("请授予电话权限以监测信号强度");
                            XXPermissions.startPermissionActivity(mActivity, permissions);
                        } else {
                            ToastUtils.show("获取权限失败");
                        }
                    }
                });
    }

    private void initSignalStrengthMonitor() {
        telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        phoneStateListener = new PhoneStateListener() {
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                super.onSignalStrengthsChanged(signalStrength);
                updateSignalInfo(signalStrength);
            }
        };

        // 注册监听器
        if (telephonyManager != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        }
    }

    int signalIntensity;

    private void updateSignalInfo(SignalStrength signalStrength) {
        if (signalStrength == null) return;
        int gsmSignalStrength = -1;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            gsmSignalStrength = signalStrength.getCellSignalStrengths().get(0).getDbm();
        } else {
            if (signalStrength.isGsm()) {
                gsmSignalStrength = signalStrength.getGsmSignalStrength() * 2 - 113;
            }
        }
        signalIntensity = gsmSignalStrength;
    }

    private void initTimerSwitch() {
        if(apiManager != null){//安卓5设置开关机
            SDK();
        } else {// 安卓7 设置开关机逻辑
            // 初始化背光定时器，立即执行一次背光检查，然后每分钟检查一次
            mHandler.removeMessages(300); // 确保不会有重复消息
            if (ConfigUtil.getTimerSwitch()) {
                Timber.tag(TAG).i("初始化背光定时器");
                checkBacklight(); // 立即检查一次以设置正确的初始状态
                mHandler.sendEmptyMessageDelayed(300, 1000 * 60);
            } else {
                Timber.tag(TAG).i("定时开关未启用，不初始化背光定时器");
                // 打开背光
                backlightOn();
            }
        }

    }

    private void SDK() {
        // 每天都需要设置一次开关机，每次开机时设置
        try{
//            apiManager.XHSetPowerOffOnTime("2018-02-08-18-00","2018-02-09-09-00",true);
            boolean timerSwitch  = ConfigUtil.getTimerSwitch();
            Timber.tag(TAG).i("SDK: 设置定时开关机 ");
            //开机时间："06:00:00"
            String enableTime = ConfigUtil.getEnableTime();
            String[] e = enableTime.split(":");
            //关机时间："23:00:00"
            String disableTime = ConfigUtil.getDisableTime();
            String[] d = disableTime.split(":");
            String day = DateUtil.getDay()+"-"+d[0]+"-"+d[1];
            String nextDay = DateUtil.getDay()+"-"+e[0]+"-"+e[1];

            Timber.tag(TAG).i("SDK: 设置开关机时间:" + day+" 开机时间："+nextDay + " 状态：" + timerSwitch);
            apiManager.XHSetPowerOffOnTime(day,nextDay,timerSwitch);
        }catch (Exception e){
            Timber.tag(TAG).i("SDK: 设置开关机异常。 " + e.getMessage());
        }
    }

    /**
     * 检查当前时间是否需要开关背光
     */
    private void checkBacklight() {
        boolean timerSwitch = ConfigUtil.getTimerSwitch();
        if (!timerSwitch) {
            return; // 如果定时开关未启用，则不处理
        }
        
        try {
            // 获取当前时间
            Calendar now = Calendar.getInstance();
            int currentHour = now.get(Calendar.HOUR_OF_DAY);
            int currentMinute = now.get(Calendar.MINUTE);
            
            // 获取配置的开关时间
            String enableTime = ConfigUtil.getEnableTime();
            String disableTime = ConfigUtil.getDisableTime();
            
            String[] enableParts = enableTime.split(":");
            String[] disableParts = disableTime.split(":");
            
            int enableHour = Integer.parseInt(enableParts[0]);
            int enableMinute = Integer.parseInt(enableParts[1]);
            
            int disableHour = Integer.parseInt(disableParts[0]);
            int disableMinute = Integer.parseInt(disableParts[1]);
            
            // 计算当前时间的分钟数
            int currentTotalMinutes = currentHour * 60 + currentMinute;
            int enableTotalMinutes = enableHour * 60 + enableMinute;
            int disableTotalMinutes = disableHour * 60 + disableMinute;
            
            boolean shouldBacklightOn = false;
            
            // 处理跨天的情况(例如: 开机时间23:00, 关机时间06:00)
            if (enableTotalMinutes >= disableTotalMinutes) {
                // 跨天情况: 当前时间大于等于开启时间或者小于关闭时间，则开启背光
                if (currentTotalMinutes >= enableTotalMinutes || currentTotalMinutes < disableTotalMinutes) {
                    shouldBacklightOn = true;
                }
            } else {
                // 正常情况: 当前时间在开启时间和关闭时间之间，则开启背光
                if (currentTotalMinutes >= enableTotalMinutes && currentTotalMinutes < disableTotalMinutes) {
                    shouldBacklightOn = true;
                }
            }
            
            // 记录详细的背光判断信息，便于调试
            Timber.tag(TAG).d("背光检查 - 当前时间: %02d:%02d, 开启时间: %02d:%02d, 关闭时间: %02d:%02d, 当前状态: %s, 应当为: %s", 
                currentHour, currentMinute, enableHour, enableMinute, disableHour, disableMinute, 
                isBacklightOn ? "开启" : "关闭", shouldBacklightOn ? "开启" : "关闭");
            
            // 根据判断结果控制背光，仅在状态需要变化时才调用控制方法
            if (shouldBacklightOn && !isBacklightOn) {
                backlightOn();
                Timber.tag(TAG).i("执行背光开启 - 当前时间: %02d:%02d", currentHour, currentMinute);
            } else if (!shouldBacklightOn && isBacklightOn) {
                backlightOff();
                Timber.tag(TAG).i("执行背光关闭 - 当前时间: %02d:%02d", currentHour, currentMinute);
            }
        } catch (Exception e) {
            Timber.tag(TAG).e(e, "检查背光状态异常");
        }
    }

    /**
     * 打开背光
     */
    public void backlightOn() {
        sendBacklightCmd(0);
        isBacklightOn = true;
    }

    /**
     * 关闭背光
     */
    public void backlightOff() {
        sendBacklightCmd(1);
        isBacklightOn = false;
    }

    Process process;
    DataOutputStream dos;
    /**
     * 发送背光指令
     * @param value
     */
    synchronized private void sendBacklightCmd(int value) {
        try {
            if (process == null) {
                process = Runtime.getRuntime().exec("su");
            }
            if (dos == null) {
                dos = new DataOutputStream(process.getOutputStream());
            }
            dos.writeBytes("echo " + value + " > /sys/class/backlight/rk28_bl/bl_power" + "\n");
            dos.flush();
        } catch (Exception e) {
            Timber.tag(TAG).e("发送背光指令异常:%s", e.getMessage());
        }
    }

    public void download(String url) {
        Timber.tag(TAG).i("开始下载文件:%s", url);
        DownloadUtil.download(this, url, new OnDownloadListener() {
            @Override
            public void onStart(File file) {

            }

            @Override
            public void onProgress(File file, int progress) {
                Timber.tag(TAG).i("下载文件:%s", progress+"%");
            }

            @Override
            public void onComplete(File file) {
                Timber.tag(TAG).i("下载成功:%s", file.getAbsolutePath());
                if(apiManager != null){//安卓5
                    // 喂狗逻辑换成，2秒一次
                    mHandler.removeMessages(200);
                    watchdogMillis = 2;
                    mHandler.sendEmptyMessage(200);
                    // 关闭喂狗
//                    apiManager.XHWatchDogEnable(false);
                    apiManager.XHInstallOnBackground(file.getAbsolutePath(), getPackageName());
                } else { // 安卓7
                    if(watchdogClient != null){
                        Timber.tag(TAG).i("安装版本前，发送一次心跳");
                        watchdogClient.sendHeartbeat();
                    }
                    InstallApkUtil.installAndStartApk(mActivity, file.getAbsolutePath());
                }
            }

            @Override
            public void onError(File file, Exception e) {
                Timber.tag(TAG).e("下载失败:%s", e.getMessage());
            }

            @Override
            public void onEnd(File file) {

            }
        });
    }
    
    /**
     * 检查MQTT连接状态
     */
    private void checkMqttConnection() {
        // 直接使用MqttUtil.isConnected()检查连接状态
        boolean isConnected = MqttUtil.isConnected();
        Timber.tag(TAG).i("检查MQTT连接状态，isConnected:%s  mqttConnected:%s", isConnected, mqttConnected);
        if (!isConnected && mqttConnected) {
            // 连接状态变化：已连接 -> 断开
            mqttConnected = false;
            Timber.tag(TAG).w("MQTT连接已断开，准备重连");
            scheduleReconnect();
        } else if (isConnected && !mqttConnected) {
            // 连接状态变化：断开 -> 已连接
            mqttConnected = true;
            reconnectAttempts = 0;
            reconnectDelay = 5000; // 重置重连延迟
            Timber.tag(TAG).i("MQTT已重新连接");
        }
    }

    // 用于标识MQTT重连消息的对象
    private final Object MQTT_RECONNECT_TOKEN = new Object();
    
    /**
     * 安排MQTT重连
     */
    private void scheduleReconnect() {
        // 仅移除与MQTT重连相关的消息
        mHandler.removeCallbacksAndMessages(MQTT_RECONNECT_TOKEN);
        
        // 计算重连延迟（指数退避策略）
        reconnectAttempts++;
        // 指数退避：延迟时间随着重试次数增加而增加，但不超过最大值
        reconnectDelay = Math.min((reconnectDelay * 2), MAX_RECONNECT_DELAY);
        
        Timber.tag(TAG).i("计划在 %d 毫秒后进行第 %d 次MQTT重连尝试", reconnectDelay, reconnectAttempts);
        
        // 使用Token标记这个消息是MQTT重连相关的
        mHandler.postAtTime(new Runnable() {
            @Override
            public void run() {
                doReconnect();
            }
        }, MQTT_RECONNECT_TOKEN, SystemClock.uptimeMillis() + reconnectDelay);
    }

    /**
     * 执行MQTT重连
     */
    private void doReconnect() {
        Timber.tag(TAG).i("正在执行MQTT重连...");
        
        // 放弃旧的连接尝试，完全重新初始化MQTT服务
        // 不尝试disconnect和connect，直接重新初始化
        MqttUtil.release(MainActivity.this); // 先完全释放MQTT连接
        
        // 延迟一小段时间后再初始化，确保资源被释放
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 重新初始化MQTT
                MqttUtil.init(MainActivity.this, new MqttManagerService.MqttEventCallbackAdapter() {
                    @Override
                    public void onConnectSuccess() {
                        Timber.tag(TAG).i("MQTT重新初始化并连接成功");
                        mqttConnected = true;
                        reconnectAttempts = 0;
                        reconnectDelay = 5000; // 重置重连延迟
                        initConnectData();
                    }
                    
                    @Override
                    public void onConnectFailure(Throwable cause) {
                        mqttConnected = false;
                        Timber.tag(TAG).e(cause, "MQTT重新初始化连接失败");
                        scheduleReconnect();
                    }
                    
                    @Override
                    public void onConnectionLost(Throwable cause) {
                        mqttConnected = false;
                        Timber.tag(TAG).e(cause, "MQTT连接丢失..");
                    }
                });
            }
        }, 1000); // 延迟1秒执行重连
    }
}